package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.common.utils.poi.HutoolExcelUtiles;
import com.ruoyi.system.domain.RecordArchives;
import com.ruoyi.system.domain.RecordFile;
import com.ruoyi.system.domain.RecordFileBook;
import com.ruoyi.system.mapper.RecordArchivesMapper;
import com.ruoyi.system.mapper.RecordFileBookMapper;
import com.ruoyi.system.mapper.RecordFileMapper;
import com.ruoyi.system.service.IRecordFileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.validation.Validator;
import java.io.File;
import java.util.List;
import java.util.Map;

/**
 * 文件管理Service业务层处理
 *
 * @author admin
 * @date 2022-03-02
 */
@Service
public class RecordFileServiceImpl implements IRecordFileService {
    private static final Logger log = LoggerFactory.getLogger(RecordFileServiceImpl.class);
    @Autowired
    protected Validator validator;
    @Autowired
    private RecordFileMapper recordFileMapper;
    @Autowired
    private RecordFileBookMapper recordFileBookMapper;
    @Autowired
    private RecordArchivesMapper recordArchivesMapper;

    /**
     * 查询文件管理
     *
     * @param fileId 文件管理主键
     * @return 文件管理
     */
    @Override
    public RecordFile selectRecordFileByFileId(Long fileId) {
        return recordFileMapper.selectRecordFileByFileId(fileId);
    }

    /**
     * 查询文件管理列表
     *
     * @param recordFile 文件管理
     * @return 文件管理
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<RecordFile> selectRecordFileList(RecordFile recordFile) {
        List<RecordFile> rList = recordFileMapper.selectRecordFileList(recordFile);
        return rList;
    }

    /***
     * 導出
     * @param archivesId
     * @return
     */
    @Override
    public File selectRecordFileExport(String archivesId) {
        RecordFile rf = new RecordFile();
        rf.setArchivesId(archivesId);
        List<RecordFile> list = recordFileMapper.selectRecordFileList(rf);
        List<File> files = CollUtil.newArrayList();
        File f = null;
        String[] filepath = null;
        String filePath = null;
        String[] imagespath = null;
        String imgpath = null;
        List<Map<String, Object>> excellist = CollUtil.newArrayList();
        for (RecordFile r : list) {
            //文件
            if (StrUtil.isNotEmpty(r.getFilePath())) {
                filepath = r.getFilePath().split(",");
                for (String s : filepath) {
                    filePath = RuoYiConfig.getProfile() + File.separator + s.replace("/profile", "");
                    f = new File(filePath);
                    files.add(f);
                    //   System.out.println(filePath);
                }
            }
            //圖片
            if (StrUtil.isNotEmpty(r.getImgPath())) {
                imagespath = r.getImgPath().split(",");
                for (String i : imagespath) {
                    imgpath = RuoYiConfig.getProfile() + File.separator + i.replace("/profile", "");
                    //   System.out.println(i);
                    f = new File(imgpath);
                    files.add(f);
                }
            }
            excellist.add(BeanUtil.beanToMap(r));
        }
        //表格
        File excelFile = HutoolExcelUtiles.RecordFileExport(JSONArray.parseArray(JSONObject.toJSONString(list)));
        files.add(excelFile);
        //生成zip
        String zipPath = RuoYiConfig.getZipPath() + archivesId + "_案卷包" + IdUtil.getSnowflake().nextIdStr() + ".zip";
        File[] zipfiles = ArrayUtil.toArray(files, File.class);

        File file = ZipUtil.zip(FileUtil.file(zipPath), false, zipfiles);
        //   System.out.println(fres.getAbsoluteFile());
        return file;
    }

    /**
     * 查询文件管理列表
     *
     * @param recordFile 文件管理
     * @return 文件管理
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<RecordFileBook> selectRecordFileListBook(RecordFileBook recordFile) {
        List<RecordFileBook> rList = recordFileBookMapper.selectRecordFileListBook(recordFile);
        return rList;
    }

    /**
     * 新增文件管理
     *
     * @param recordFile 文件管理
     * @return 结果
     */
    @Override
    public int insertRecordFile(RecordFile recordFile) {
        RecordArchives arch = recordArchivesMapper.selectRecordArchivesByArchivesId(recordFile.getArchivesId());
        if (arch == null) {
            throw new ServiceException("未找到ID为" + recordFile.getArchivesId() + "的案卷");
        } else {
            recordFile.setObjInt6(SecurityUtils.getUserId());// 创建人ID，用于数据权限
            recordFile.setCreateBy(SecurityUtils.getLoginUser().getUsername());
            recordFile.setCreateTime(DateUtils.getNowDate());
            return recordFileMapper.insertRecordFile(recordFile);
        }
    }

    /**
     * 修改文件管理
     *
     * @param recordFile 文件管理
     * @return 结果
     */
    @Override
    public int updateRecordFile(RecordFile recordFile) {
        recordFile.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        recordFile.setUpdateTime(DateUtils.getNowDate());
        return recordFileMapper.updateRecordFile(recordFile);
    }

    /**
     * 批量删除文件管理
     *
     * @param fileIds 需要删除的文件管理主键
     * @return 结果
     */
    @Override
    public int deleteRecordFileByFileIds(Long[] fileIds) {
        return recordFileMapper.deleteRecordFileByFileIds(fileIds);
    }

    /**
     * 删除文件管理信息
     *
     * @param fileId 文件管理主键
     * @return 结果
     */
    @Override
    public int deleteRecordFileByFileId(Long fileId) {
        return recordFileMapper.deleteRecordFileByFileId(fileId);
    }

    @Override
    @Transactional
    public String importFile(List<RecordFile> fileList, String operName) {
        // 设置回滚点
        Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
        if (StringUtils.isNull(fileList) || fileList.size() == 0) {
            throw new ServiceException("导入文件数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (RecordFile file : fileList) {
            try {
                BeanValidators.validateWithException(validator, file);
                file.setCreateBy(operName);
                this.insertRecordFile(file);
                successNum++;
                successMsg.append("<br/>" + successNum + "、文件 " + file.getDocTitle() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、文件 " + file.getDocTitle() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
                //手工回滚异常
                TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            //手工回滚异常
            TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
